package com.zhiyu.util;

import java.util.Date;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

@ConfigurationProperties(prefix = "config.jwt")
@Component
public class JWTUtil {
	private String secret; // 加密所用密钥

	private long expire; // 过期时间

	private String header; // 指定token存放在请求头的哪个字段

	/**
	 * 生成token
	 *
	 * @param subject 签发主体
	 *
	 * @return 生成的token
	 *
	 */
	public String createToken(String subject) {
		Date nowDate = new Date(); // 当前时间
		Date expireDate = new Date(nowDate.getTime() + expire * 1000); // 过期时间=当前时间+时间戳

		return Jwts.builder().setHeaderParam("typ", "JWT") // 令牌类型
				.setSubject(subject) // 主题
				.setIssuedAt(nowDate).setExpiration(expireDate).signWith(SignatureAlgorithm.HS512, secret).compact();
	}

	/**
	 * 获取token中的注册信息
	 *
	 * @param token
	 */
	public Claims getTokenClaim(String token) {
		try {
			return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 检验token是否有效
	 *
	 * @param token
	 *
	 * 如果token为null，或者token过期，或者token签名不一致，返回false，否则返回true
	 *
	 */
	public boolean verify(String token) {
		if (token == null || getTokenClaim(token) == null || isTokenExpired(token))
			return false;
		return true;
	}

	/**
	 * 验证token是否过期失效
	 *
	 * @param token
	 *
	 * @return 失效返回true，未失效返回false
	 */
	public boolean isTokenExpired(String token) {
		Date expirationTime = getExpirationDate(token);
		return expirationTime.before(new Date());
	}

	/**
	 * 获取token的失效时间
	 *
	 * @param token
	 *
	 * @return 失效日期
	 */
	public Date getExpirationDate(String token) {
		return getTokenClaim(token).getExpiration();
	}

	/**
	 * 获取token的subject
	 *
	 * @param token
	 *
	 * @return subject
	 */
	public String getSubject(String token) {
		Claims claims = getTokenClaim(token);
		if(claims == null)
			return null;

		return claims.getSubject();
	}

	public Date getIssuedAtDate(String token) {
		return getTokenClaim(token).getIssuedAt();
	}

	public String getHeader() {
		return header;
	}

	public String getSecret() {
		return secret;
	}

	public void setSecret(String secret) {
		this.secret = secret;
	}

	public long getExpire() {
		return expire;
	}

	public void setExpire(long expire) {
		this.expire = expire;
	}

	public void setHeader(String header) {
		this.header = header;
	}


}
